package com.topnav.mc.admin.controller;

import com.alibaba.fastjson2.JSONObject;
import com.dtflys.forest.annotation.URLEncode;
import com.js.lib.result.Result;
import com.js.lib.utils.ResultUtil;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.entity.GbServer;
import com.topnav.mc.admin.service.IDeviceService;
import com.topnav.mc.admin.service.IGbServerService;
import com.topnav.mc.common.Constant;
import static com.topnav.mc.exception.ExceptionMsg.*;

import com.topnav.mc.exception.ExceptionMsg;
import com.topnav.mc.involve.http.HttpClientUtil;
import com.topnav.mc.involve.request.RequestUtils;
import com.topnav.mc.uitls.GbServerUtil;
import com.topnav.mc.uitls.ResultErrorUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 国标音视频录像回放等功能都要这里
 * @Author: kenny
 * @Date: 2024/1/15 10:38
 */
@RestController
@CrossOrigin
@RequestMapping("admin/gb/video/record")
@Slf4j
public class GbVideoReplay {
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IGbServerService gbServerService;

    /**
     * 查询录像
     * @param param
     * deviceCode
     * channelCode
     * fromTime
     * toTime
     * @return
     */
    @PostMapping("/query")
    @ResponseBody
    public DeferredResult<Result> query(@RequestBody Map<String,String> param){

        //@PathVariable String deviceCode, @PathVariable String channelCode, String startTime, String endTime
        DeferredResult<Result> result = this.newDeferredResult();
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });

        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/gb/record/query/%s/%s?startTime=%s&endTime=%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("fromTime"),
                    param.get("toTime"));
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());
            //不支持带下划线的请求 狗日
            url = String.format("http://%s:%s/api/gb/record/query/%s/%s?startTime=%s&endTime=%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("fromTime"),
                    param.get("toTime")
            );
        }
        //空格
        final String uri = url.replaceAll(" ","%20");

        //String url="https://192.168.0.129:18086/play/playstart/44010200492000000020/44030000492000000020";
        //String url="https://www.baidu.com/";
        new Thread(()->{
            HttpClientUtil.get(uri, Constant.PLAY_TIMEOUT*1000,
                    null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();

        return result;
        //http://192.168.0.129:18080/api/gb_record/query/44010200492000000020/44030000492000000020?startTime=2024-01-16%2000:00:00&endTime=2024-01-16%2023:59:59
    }

    /**
     * 发起视频回放请求
     * @param param
     * deviceCode
     * channelCode
     * fromTime
     * toTime
     * @return
     */
    @PostMapping("/start")
    public DeferredResult<Result> replay(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT + 1)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/playback/start/%s/%s?startTime=%s&endTime=%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("fromTime"),
                    param.get("toTime"));
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());
            url = String.format("http://%s:%s/api/playback/start/%s/%s?startTime=%s&endTime=%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("fromTime"),
                    param.get("toTime")
            );
        }

        String uri = url.replaceAll(" ","%20");
        new Thread(()->{
            HttpClientUtil.get(uri, (Constant.PLAY_TIMEOUT+2)*1000,null,
                new FutureCallback<HttpResponse>() {
                    @SneakyThrows
                    @Override
                    public void completed(HttpResponse response) {
                        HttpEntity entity = response.getEntity();
                        String res = EntityUtils.toString(entity);
                        System.out.println("远程API 响应--->" + res);
                        JSONObject json = JSONObject.parseObject(res);
                        if (json.getInteger("code") != 0){
                            log.error(">>>>>> {}",json.getString("msg"));
                            result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                        }else{
                            result.setResult(Result.ok(json.getJSONObject("data")));
                        }
                    }
                    @Override
                    public void failed(Exception e) {
                        log.error(e.toString());
                        if (e instanceof ConnectException){
                            //无法连接国标服务器
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                        }else{
                            log.error(">>>>>>>> {}",e.toString());
                            result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                        }
                    }
                    @Override
                    public void cancelled() {
                        log.error("操作已被用户取消！");
                        //操作已被用户取消
                        result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                    }
                },
                (err)->{
                    log.error(">>>>>>>> {}",err.toString());
                    result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                }
            );
        }).start();
        //'/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
        return result;
    }

    /**
     * 回放停止
     * @param param
     * deviceCode
     * channelCode
     * streamId
     * @return
     */
    @PostMapping("/stop")
    public DeferredResult<Result> replayStop(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/playback/stop/%s/%s/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId"));
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());
            url = String.format("http://%s:%s/api/playback/stop/%s/%s/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId")
            );
        }
        final String url1 = url;
        //url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        //'/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
        return result;
    }

    /**
     * 回放继续
     * @param param
     * @return
     */
    @PostMapping("/resume")
    public DeferredResult<Result> resume(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/playback/resume/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("streamId"));
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/api/playback/resume/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("streamId")
            );
        }

        //url:     /api/playback/resume/' + this.streamId
        final String url1 = url;
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    /**
     * 回放暂停
     * @param param
     * @return
     */
    @PostMapping("/pause")
    public DeferredResult<Result> pause(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/playback/pause/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("streamId"));
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/api/playback/pause/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("streamId")
            );
        }
        final String url1 = url;
        //url:     /api/playback/resume/' + this.streamId
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    @PostMapping("/speed")
    public DeferredResult<Result> speed(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/playback/speed/%s/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("streamId"),
                    param.get("command")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());
            url = String.format("http://%s:%s/api/playback/speed/%s/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("streamId"),
                    param.get("command")
            );
        }
        final String url1 = url;
        //url: `/api/playback/speed/${this.streamId }/${command}`
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    /**
     * 国标录像下载
     * @param param
     * @return
     */
    @PostMapping("/download/start")
    public DeferredResult<Result> downloadStart(@RequestBody Map<String,String> param) throws UnsupportedEncodingException {
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应！！
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/gb_record/download/start/%s/%s?startTime=%s&endTime=%s&downloadSpeed=1",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    URLEncoder.encode(param.get("fromTime"),"utf-8"),
                    URLEncoder.encode(param.get("toTime"),"utf-8")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/api/gb_record/download/start/%s/%s?startTime=%s&endTime=%s&downloadSpeed=1",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    URLEncoder.encode(param.get("fromTime"),"utf-8"),
                    URLEncoder.encode(param.get("toTime"),"utf-8")
            );
        }
        log.info(url);
        final String url1 = url;//URLEncoder.encode(url,"utf-8");
        //'/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + row.endTime + '&downloadSpeed=4'
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    /**
     * 下载停止
     * @param param
     * @return
     */
    @PostMapping("/download/stop")
    public DeferredResult<Result> downloadStop(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/gb_record/download/stop/%s/%s/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/api/gb_record/download/stop/%s/%s/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId")
            );
        }
        final String url1 = url;
        //url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    @PostMapping("/download/task/add")
    public DeferredResult<Result> downloadTaskAdd(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/record_proxy/%s/api/record/file/download/task/add?app=%s&stream=%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("mediaServerId"),
                    param.get("app"),
                    param.get("streamId")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/record_proxy/%s/api/record/file/download/task/add?app=%s&stream=%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("mediaServerId"),
                    param.get("app"),
                    param.get("streamId")
            );
        }
        final String url1 = url;
        //if param.get("mediaServerId")
        //url: '/record_proxy/${this.mediaServerId}/api/record/file/download/task/add
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    @PostMapping("/download/task/list")
    public DeferredResult<Result> downloadTaskList(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/record_proxy/%s/api/record/file/download/task/list?app=%s&stream=%s&taskId=&s&isEnd=1",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("mediaServerId"),
                    param.get("app"),
                    param.get("streamId"),
                    param.get("taskId")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/record_proxy/%s/api/record/file/download/task/list?app=%s&stream=%s&taskId=&s&isEnd=1",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("mediaServerId"),
                    param.get("app"),
                    param.get("streamId"),
                    param.get("taskId")
            );
        }
        final String url1 = url;
        //if param.get("mediaServerId")
        //url: '/record_proxy/${this.mediaServerId}/api/record/file/download/task/add

/*        app: this.app,
                stream: this.stream,
                taskId: this.taskId,
                isEnd: true,*/

        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    @PostMapping("/download/task/progress")
    public DeferredResult<Result> downloadTaskProgress(@RequestBody Map<String,String> param){
        DeferredResult<Result> result = new DeferredResult<>((Constant.PLAY_TIMEOUT)*1000L);
        result.onTimeout(() -> {
            //服务端超时未响应
            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_TIMEOUT_NOT_RESPONED));
        });
        Device device = deviceService.getFromCache(param.get("deviceCode"));
        String url=null;
        if (GbServerUtil.get() != null){
            url = String.format("http://%s:%s/api/gb_record/download/progress/%s/%s/%s",
                    GbServerUtil.getIp(),GbServerUtil.getPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId")
            );
        }else{
            GbServer gbServer = gbServerService.getFromCache(device.getGbServerId().toString());

            url = String.format("http://%s:%s/api/gb_record/download/progress/%s/%s/%s",
                    gbServer.getHost(),
                    gbServer.getApiPort(),
                    param.get("deviceCode"),
                    param.get("channelCode"),
                    param.get("streamId")

            );
        }
        final String url1 = url;
        //url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}`
        new Thread(()->{
            HttpClientUtil.get(url1, (Constant.PLAY_TIMEOUT)*1000,null,
                    new FutureCallback<HttpResponse>() {
                        @SneakyThrows
                        @Override
                        public void completed(HttpResponse response) {
                            HttpEntity entity = response.getEntity();
                            String res = EntityUtils.toString(entity);
                            System.out.println("远程API 响应--->" + res);
                            JSONObject json = JSONObject.parseObject(res);
                            if (json.getInteger("code") != 0){
                                log.error(">>>>>> {}",json.getString("msg"));
                                result.setResult(ResultErrorUtil.byExceptionMsg(ExceptionMsg.getWvpException(json.getInteger("code"),json.getString("msg"))));
                            }else{
                                result.setResult(Result.ok(json.getJSONObject("data")));
                            }
                        }
                        @Override
                        public void failed(Exception e) {
                            log.error(e.toString());
                            if (e instanceof ConnectException){
                                //无法连接国标服务器
                                result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_SERVER_UNABLED_TO_CONNECT_NS_SERVER));
                            }else{
                                log.error(">>>>>>>> {}",e.toString());
                                result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,e.toString()));
                            }
                        }
                        @Override
                        public void cancelled() {
                            log.error("操作已被用户取消！");
                            result.setResult(ResultErrorUtil.byExceptionMsg(ERROR_OPERATION_HAS_BEEN_CANCELS_BY_USER));
                        }
                    },
                    (err)->{
                        log.error(err.toString());
                        log.error(">>>>>>>> {}",err.toString());
                        result.setResult(ResultErrorUtil.byExceptionMsg(EXCEPTION,err.toString()));
                    }
            );
        }).start();
        return result;
    }

    private DeferredResult<Result> newDeferredResult(){
        return new DeferredResult<>((Constant.PLAY_TIMEOUT+1)*1000L);
    }


}

